package com.collabscm.pf.dao;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.collabscm.pf.cache.Cache;
import com.collabscm.pf.cache.CacheManager;
import com.collabscm.pf.cache.CacheManagerFactory;
import com.collabscm.pf.logging.Logger;
import com.collabscm.pf.logging.LoggerFactory;
import com.collabscm.pf.vo.PageObject;
import com.collabscm.pf.vo.QueryParameters;

/**
 * 查询结构缓存，将分页查询内容进行缓存，将相同条件的内容进行缓存。
 *
 * @author Zeng Raoxing
 */
public class QueryCache {
	/**
	 * 此处的：Key为一个String，此String的来源于：entityClass、namedQuery以及QueryParameters的组合，对应的是PageObject对象
	 */
	private static Cache<String, PageObject<?>> queryCache;
	static {
		@SuppressWarnings("unchecked")
		CacheManager<Cache<String, PageObject<?>>> cm = CacheManagerFactory.getCacheManager();
		queryCache = cm.getCache("platform/dao/QueryCache");
	}
	/**
	 * 用于Remove时根据Class对象找到其对应的所有缓存。
	 */
	private static Map<Class<?>, List<String>> cacheKeyMap = new HashMap<Class<?>, List<String>>();
	private static final Logger logger = LoggerFactory.getLogger(QueryCache.class);
	
	/**
	 * 从缓存中查找分页对象
	 * 
	 * @param entityClass
	 * @param namedQuery
	 * @param parameters
	 * @return
	 */
	public static PageObject<?> findPageObject(Class<?> entityClass, String namedQuery, QueryParameters parameters) {
		return queryCache.get(createCacheKey(entityClass, namedQuery, parameters));
	}
	
	/**
	 * 将缓存对象设置到缓存中
	 * 
	 * @param entityClass
	 * @param namedQuery
	 * @param parameters
	 * @param pageObject
	 */
	public static void putPageObject(Class<?> entityClass, String namedQuery, QueryParameters parameters, PageObject<?> pageObject) {
		String key = createCacheKey(entityClass, namedQuery, parameters);
		List<String> keys = cacheKeyMap.get(entityClass);
		if(keys == null) {
			keys = new ArrayList<String>();
			cacheKeyMap.put(entityClass, keys);
		}
		keys.add(key);
		queryCache.put(createCacheKey(entityClass, namedQuery, parameters), pageObject);
	}
	
	/**
	 * 删除此类缓存的所有内容
	 * @param entityClass
	 */
	public static void removeCache(Class<?> entityClass) {
		List<String> cacheKeys = cacheKeyMap.get(entityClass);
		for(String key: cacheKeys) {
			queryCache.remove(key);
		}
		//清空缓存以便后续再用时不用重新创建
		cacheKeys.clear();
		logger.debug("删除了{}对应的所有缓存.", entityClass);
	}
	
	/**
	 * 生成缓存的Key
	 * 
	 * @param entityCalss 对应的实体的Class
	 * @param namedQuery  对应的查询的名称
	 * @param parameters  具体的参数
	 */
	public static String createCacheKey(Class<?> entityClass, String namedQuery, QueryParameters parameters) {
		StringBuffer sb = new StringBuffer(entityClass.getName());
		sb.append("_").append(namedQuery).append("_").append(parameters);
		logger.trace("根据生成的Key为{}", sb);
		return sb.toString();
	}

}
